import axios from 'axios';
import { message as $message } from 'ant-design-vue';
import type { AxiosRequestConfig } from 'axios';
import { ACCESS_TOKEN_KEY } from '@/enums/cacheEnum';
import { Storage, Session } from '@/utils/Storage';
import { useUserStore } from '@/store/modules/user';
import { uniqueSlash } from '@/utils/urlUtils';
import { tansParams } from '@/utils/common';
import { useRouter } from 'vue-router';
import { router } from '@/router';
import {LOGIN_NAME} from "@/router/constant"

export interface RequestOptions {
  /** 当前接口权限, 不需要鉴权的接口请忽略， 格式：sys:user:add */
  permCode?: string;
  /** 是否直接获取data，而忽略message等 */
  isGetDataDirectly?: boolean;
  /** 请求成功是提示信息 */
  successMsg?: string;
  /** 请求失败是提示信息 */
  errorMsg?: string;
  /** 是否mock数据请求 */
  isMock?: boolean;
  /** 自定义超时时间(毫秒) */
  timeout?: number;
}

const UNKNOWN_ERROR = '未知错误，请重试';

const errorCode = {
  401: '认证失败，无法访问系统资源',
  403: '当前操作没有权限',
  404: '访问资源不存在',
  default: '系统未知错误，请反馈给管理员',
};

// window.$count = 0;

/** 真实请求的路径前缀 */
const baseApiUrl = import.meta.env.VITE_BASE_API;
/** mock请求路径前缀 */
const baseMockUrl = import.meta.env.VITE_MOCK_API;

const service = axios.create({
  // baseURL: baseApiUrl,
  //timeout: 6000,
});

service.interceptors.request.use(
  (config) => {
    // 是否需要防止数据重复提交
    const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
    // 让每个请求携带自定义token
    config.headers.Authorization = `Bearer ${Storage.get(ACCESS_TOKEN_KEY)}`;  
    // get请求映射params参数
    if (config.method === 'get' && config.params) {
      let url = `${config.url}?${tansParams(config.params)}`;
      url = url.slice(0, -1);
      config.params = {};
      config.url = url;
    }
    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
      const requestObj = {
        url: config.url,
        data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
        time: new Date().getTime(),
      };
      const sessionObj = Session.get('sessionObj');
      if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
        Session.set('sessionObj', requestObj);
      } else {
        const sUrl = sessionObj.url; // 请求地址
        const sData = sessionObj.data; // 请求数据
        const sTime = sessionObj.time; // 请求时间
        const interval = 1000; // 间隔时间(ms)，小于此时间视为重复提交

        if (
          sData === requestObj.data &&
          requestObj.time - sTime < interval &&
          sUrl === requestObj.url
        ) {
          Session.set('sessionObj', requestObj);
          // const message = '数据正在处理，请勿重复提交';
          // console.warn(`[${sUrl}]: ${message}`);
          // return Promise.reject(new Error(message));
        } else {
          Session.set('sessionObj', requestObj);
        }
      }
    }
    return config;
  },
  (error) => {
    Promise.reject(error);
  },
);

service.interceptors.response.use(
  (res) => {
    // 未设置状态码则默认成功状态
    const code = res.status || 200;
    // 获取错误信息
    const msg = errorCode[code] || res.data.msg || errorCode.default;
    // 二进制数据则直接返回
    if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
      return res;
    }
    if (code === 401) {
      //  store.dispatch('store/account/logout');
      $message.error(msg || UNKNOWN_ERROR);
      return Promise.reject(new Error(msg));
    } else if (code === 500) {
      $message.error(msg || UNKNOWN_ERROR);
      return Promise.reject(new Error(msg));
    } else if (code !== 200) {
      // Notification.error({
      //   title: msg,
      // });
      $message.error(msg || UNKNOWN_ERROR);
      return Promise.reject('error');
    } else {
      return res.data;
    }
  },
  async (err) => {
    console.log(`error => ${err}`);
    let { message } = err;
    // if (err.message.includes('401')) {
    //   await useUserStore().logout()
    //   router.replace({ name: LOGIN_NAME,query: { redirect: location.hash.slice(1) }});
    //   return Promise.reject(err);
    // }
    if (message === 'ERR_BAD_REQUEST') {
      message = '后端接口连接异常';
    } else if (message.includes('timeout')) {
      message = '系统接口请求超时';
    } else if (message.includes('401')) {
      message = '登录超时，请重新登录';
    }
    $message.error(message, 5);
    return Promise.reject(err);
  },
);

export type Response<T = any> = {
  code: number;
  message: string;
  data: T;
  result?: T;
};

export type BaseResponse<T = any> = Promise<Response<T>>;

/**
 *
 * @param method - request methods
 * @param url - request url
 * @param data - request data or params
 */
export const request = async <T = any>(
  config: AxiosRequestConfig,
  options: RequestOptions = {},
): Promise<T> => {
  try {
    const { successMsg, errorMsg, permCode, isMock, isGetDataDirectly = false,timeout } = options;
    const mergedConfig: AxiosRequestConfig = {
      ...config,
      timeout: typeof timeout !== 'undefined' 
        ? timeout          // 显式设置时使用 options.timeout
        : 6000   // 否则保留原有 config.timeout
    };
    // 如果当前是需要鉴权的接口 并且没有权限的话 则终止请求发起
    if (permCode && !useUserStore().perms.includes(permCode)) {
      return $message.error('你没有访问该接口的权限，请联系管理员！');
    }
    const fullUrl = `${(isMock ? baseMockUrl : baseApiUrl) + mergedConfig.url}`;
    mergedConfig.url = uniqueSlash(fullUrl);

    const res = await service.request(mergedConfig);
    successMsg && $message.success(successMsg);
    errorMsg && $message.error(errorMsg);
    return isGetDataDirectly ? res.data : res;
  } catch (error: any) {
    return Promise.reject(error);
  }
};
